package com.gitee.l0km.xthrift.thrift.codec;

import java.util.List;

import org.apache.thrift.protocol.TProtocol;

import com.facebook.swift.codec.ThriftCodec;
import com.facebook.swift.codec.internal.builtin.ListThriftCodec;
import com.facebook.swift.codec.metadata.ThriftType;
import com.gitee.l0km.xthrift.thrift.protocol.TProtocolReaderXthrift;
import com.gitee.l0km.xthrift.thrift.protocol.TProtocolWriterXthrift;
import com.gitee.l0km.xthrift.thrift.reflection.FieldSupport;
import com.google.common.base.Preconditions;

/**
 * 重写{@link #read(TProtocol)},{@link #write(List, TProtocol)}方法,
 * 使用{@link TProtocolWriterXthrift},{@link TProtocolReaderXthrift}替代原生的{@code TProtocolReader,TProtocolWriter}
 * @author guyadong
 *
 * @param <T>
 * @since 1.5.0
 */
public class ListThriftCodecXthrift<T> extends ListThriftCodec<T> {
	private final ThriftCodec<T> elementCodec;

	private ListThriftCodecXthrift(ThriftType type, ThriftCodec<T> elementCodec) {
		super(type, elementCodec);
		this.elementCodec = elementCodec;
	}

	@Override
	public List<T> read(TProtocol protocol) throws Exception {
		return TProtocolReaderXthrift.of(protocol).readList(elementCodec);
	}

	@Override
	public void write(List<T> value, TProtocol protocol) throws Exception {
		Preconditions.checkNotNull(value, "value is null");
		TProtocolWriterXthrift.of(protocol).writeList(elementCodec, value);
	}
	/**
	 * 如果是List类型编解码器则替换为自定义的{@link ListThriftCodecXthrift}实例以支持不带类型的标准JSON格式数据协议 
	 * @param <T>
	 * @param codec
	 */
	@SuppressWarnings("unchecked")
	public static <T> ThriftCodec<T> usingIfList(ThriftCodec<T> codec) {
		if ((codec instanceof ListThriftCodec) && !(codec instanceof ListThriftCodecXthrift)) {
			return (ThriftCodec<T>) new ListThriftCodecXthrift<>(codec.getType(),
					FieldSupport.<ThriftCodec<T>>fieldValueOf(codec, "elementCodec"));
		}
		return codec;
	}
}
